home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_300
/
359_11
/
patch5.000
/
GO32_CONTROL.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-09-11
|
12KB
|
530 lines
/* This is file CONTROL.C */
/*
** Copyright (C) 1991 DJ Delorie, 24 Kirsten Ave, Rochester NH 03867-2954
**
** This file is distributed under the terms listed in the document
** "copying.dj", available from DJ Delorie at the address above.
** A copy of "copying.dj" should accompany this file; if not, a copy
** should be available from where this file was obtained. This file
** may not be distributed without a verbatim copy of "copying.dj".
**
** This file is distributed WITHOUT ANY WARRANTY; without even the implied
** warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
/* Modified for VCPI Implement by Y.Shibata Aug 5th 1991 */
/* History:87,1 */
#include <dos.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <string.h>
#include "build.h"
#include "types.h"
#include "gdt.h"
#include "idt.h"
#include "tss.h"
#include "valloc.h"
#include "utils.h"
#include "syms.h"
#include "graphics.h"
#include "mono.h"
#include "vcpi.h"
TSS *tss_ptr;
int debug_mode = 0;
int self_contained;
long header_offset = 0;
int use_ansi=0;
int use_mono=0;
int redir_1_mono=0;
int redir_2_mono=0;
int redir_2_1=0;
int redir_1_2=0;
static int old_video_mode;
int16 ems_handle=0; /* Get EMS Handle */
word16 vcpi_installed = 0; /* VCPI Installed Flag */
extern near go32();
extern near go_real_mode();
extern void vcpi_flush(); /* VCPI Memory All Cleared */
extern int was_exception;
extern near ivec0(), ivec1(), ivec7(), ivec75();
extern near interrupt_common(), page_fault();
extern near test();
extern word32 far *pd;
fillgdt(int sel, word32 limit, word32 base, word8 type, int G)
{
GDT_S *g;
g = gdt+sel;
if (G & 2)
limit = limit >> 12;
g->lim0 = limit & 0xffff;
g->lim1 = (limit>>16) & 0x0f;
g->base0 = base & 0xffff;
g->base1 = (base>>16) & 0xff;
g->base2 = (base>>24) & 0xff;
g->stype = type;
g->lim1 |= G * 0x40;
}
word32 ptr2linear(void far *ptr)
{
return (word32)FP_SEG(ptr) * 16L + (word32)FP_OFF(ptr);
}
setup_tss(TSS *t, int (*eip)())
{
memset(t, 0, sizeof(TSS));
t->tss_cs = g_rcode*8;
t->tss_eip = (long)FP_OFF(eip);
t->tss_ss = g_rdata*8;
t->tss_esp = (long)FP_OFF(t->tss_stack);
t->tss_ds = g_rdata*8;
t->tss_es = g_rdata*8;
t->tss_fs = g_rdata*8;
t->tss_gs = g_rdata*8;
t->tss_eflags = 0x0200;
t->tss_iomap = 0xffff; /* no map */
}
exit_func()
{
int i;
dalloc_uninit();
uninit_controllers();
xms_free();
if ((ems_handle)&&(ems_handle != -1))
ems_free(ems_handle); /* Deallocated EMS Page */
if (vcpi_installed)
vcpi_flush(); /* Deallocated VCPI Pages */
#if TOPLINEINFO
for (i=0; i<80; i++)
poke(screen_seg, i*2, 0x0720);
#endif
}
int ctrl_c_flag = 0;
ctrlbrk_func()
{
#if DEBUGGER
ctrl_c_flag = 1;
#else
exit(3);
#endif
}
usage(char *s)
{
printf("Usage: %s [program [options . . . ]]\n", s);
_exit(1);
}
int have_80387;
int use_xms=0;
static word32 push32(void *ptr, int len);
main(int argc, char **argv, char **envp)
{
int i, n, set_brk=0, emu_installed=0;
struct stat stbuf;
char *cp, *path, *argv0, *emu_fn=0;
unsigned short header[3];
if (xms_installed())
use_xms = 1;
old_video_mode = peekb(0x40, 0x49);
if (strcmp(argv[1], "!proxy") == 0)
{
int oseg, optr, i;
int far *oargv;
char far *oargve;
sscanf(argv[2], "%x", &argc);
sscanf(argv[3], "%x", &oseg);
sscanf(argv[4], "%x", &optr);
oargv = MK_FP(oseg, optr);
argv = (char **)malloc(sizeof(char *) * (argc+1));
for (i=0; i<argc+1; i++)
{
if (oargv[i] == 0)
{
argv[i] = 0;
break;
}
oargve = MK_FP(oseg, oargv[i]);
for (optr=0; oargve[optr]; optr++);
argv[i] = (char *)malloc(optr+1);
for (optr=0; oargve[optr]; optr++)
argv[i][optr] = oargve[optr];
argv[i][optr] = 0;
}
}
ems_handle = emm_present();
switch (cputype())
{
case 1:
if ((ems_handle)&&(ems_handle != -1))
ems_free(ems_handle);
fprintf(stderr, "CPU must be a 386 to run this program.\n");
exit(1);
case 2:
if (ems_handle)
{
if (vcpi_installed = vcpi_present())
break;
else if (ems_handle != -1)
ems_free(ems_handle);
}
fprintf(stderr, "CPU must be in REAL mode (not V86 mode) to run this program.\n");
exit(1);
}
if (peekb(0x40,0x49) == 7)
screen_seg = 0xb000;
_fmode = O_BINARY;
cp = getenv("GO32");
path = 0;
if (cp)
while (1)
{
char sw[100];
char val[100];
if (sscanf(cp, "%s%n", sw, &i) < 1)
break;
cp += i;
if (strcmp(sw, "ansi") == 0)
use_ansi = 1;
else if (strcmp(sw, "mono") == 0)
use_mono = 1;
else if (strcmp(sw, "2r1") == 0)
redir_2_1 = 1;
else if (strcmp(sw, "1r2") == 0)
redir_1_2 = 1;
else if (strcmp(sw, "2rm") == 0)
redir_2_mono = 1;
else if (strcmp(sw, "1rm") == 0)
redir_1_mono = 1;
else
{
val[0] = 0;
sscanf(cp, "%s%n", val, &i);
cp += i;
if (val[0] == 0)
break;
}
if (strcmp(sw, "driver") == 0)
{
if (path) free(path);
path = strdup(val);
}
else if (strcmp(sw, "tw") == 0)
gr_def_tw = atoi(val);
else if (strcmp(sw, "th") == 0)
gr_def_th = atoi(val);
else if (strcmp(sw, "gw") == 0)
gr_def_gw = atoi(val);
else if (strcmp(sw, "gh") == 0)
gr_def_gh = atoi(val);
else if (strcmp(sw, "emu") == 0)
{
if (emu_fn) free(emu_fn);
emu_fn = strdup(val);
}
}
#if ! DEBUGGER
use_mono = 0;
#endif
setup_graphics_driver(path);
if (path) free(path);
if (use_mono)
{
use_ansi = 0;
screen_seg = 0xb000;
}
setbuf(stdin, 0);
atexit((atexit_t)exit_func);
ctrlbrk(ctrlbrk_func);
n = (int)ivec1-(int)ivec0;
for (i=0; i<256; i++)
{
idt[i].selector = g_rcode*8;
idt[i].stype = 0x8e00;
idt[i].offset0 = FP_OFF((int)ivec0+n*i);
idt[i].offset1 = 0;
}
idt[14].selector = g_ptss*8;
idt[14].stype = 0x8500;
idt[14].offset0 = 0;
idt[14].offset1 = 0;
cp = getenv("387");
if (cp)
if (tolower(cp[0]) == 'n')
have_80387 = 0;
else if (tolower(cp[0]) == 'y')
have_80387 = 1;
else
have_80387 = detect_80387();
else
have_80387 = detect_80387();
if (have_80387)
{
idt[7].offset0 = (int)ivec7;
idt[7].offset1 = 0;
idt[0x75].offset0 = (int)ivec75;
idt[0x75].offset1 = 0;
}
if (cp && (tolower(cp[0]) == 'q'))
if (have_80387)
printf("An 80387 has been detected.\n");
else
printf("No 80387 has been detected.\n");
fillgdt(g_zero, 0, 0, 0, 0);
fillgdt(g_gdt, sizeof(gdt), ptr2linear(gdt), 0x92, 0);
fillgdt(g_idt, sizeof(idt), ptr2linear(idt), 0x92, 0);
fillgdt(g_rcode, 0xffff, (word32)_CS*16L, 0x9a, 0);
fillgdt(g_rdata, 0xffff, (word32)_DS*16L, 0x92, 0);
fillgdt(g_core, 0xffffffffL, 0, 0x92, 3);
fillgdt(g_acode, 0xefffffffL, 0x10000000L, 0x9a, 3);
fillgdt(g_adata, 0xefffffffL, 0x10000000L, 0x92, 3);
fillgdt(g_ctss, sizeof(TSS), ptr2linear(&c_tss), 0x89, 3);
fillgdt(g_atss, sizeof(TSS), ptr2linear(&a_tss), 0x89, 3);
fillgdt(g_ptss, sizeof(TSS), ptr2linear(&p_tss), 0x89, 3);
fillgdt(g_itss, sizeof(TSS), ptr2linear(&i_tss), 0x89, 3);
fillgdt(g_rc32, 0xffff, (word32)_CS*16L, 0x9a, 3);
fillgdt(g_grdr, 0xffff, (word32)gr_paging_segment*16L, 0x9a, 0);
setup_tss(&c_tss, go_real_mode);
setup_tss(&a_tss, go_real_mode);
setup_tss(&o_tss, go_real_mode);
setup_tss(&f_tss, go_real_mode);
setup_tss(&i_tss, interrupt_common);
setup_tss(&p_tss, page_fault);
tss_ptr = &a_tss;
argv0 = argv[0];
for (i=0; argv0[i]; i++)
{
if (argv0[i] == '\\')
argv0[i] = '/';
argv0[i] = tolower(argv0[i]);
}
if (strcmp(argv[1], "-nobrk") == 0)
{
set_brk=1;